package nancal.mp

import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.base.utils.SpringUtil
import nbcp.base.utils.StringUtil
import nbcp.flux.EnableFluxFeign
import org.slf4j.LoggerFactory
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
import org.springframework.boot.context.event.ApplicationStartedEvent
import org.springframework.boot.web.context.WebServerApplicationContext
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.cloud.gateway.event.RefreshRoutesEvent
import org.springframework.cloud.openfeign.EnableFeignClients
import org.springframework.context.ApplicationContext
import org.springframework.context.event.EventListener
import org.springframework.http.server.reactive.ServerHttpRequest
import java.util.*
import kotlin.concurrent.thread


fun ServerHttpRequest.findParameterValue(name: String): String {
    this.queryParams.getFirst(name)
        .apply {
            if (this.isNullOrEmpty() == false) {
                return this;
            }
        }

    this.headers.getFirst(name)
        .apply {
            if (this.isNullOrEmpty() == false) {
                return this;
            }
        }
    return "";
}

@SpringBootApplication(
    exclude = arrayOf(
        DataSourceAutoConfiguration::class,
        RabbitAutoConfiguration::class,
        ElasticsearchDataAutoConfiguration::class,
//        MongoAutoConfiguration::class,
//        CrossFilterConfig::class
    )
)
@EnableDiscoveryClient
@EnableFeignClients(value = arrayOf("nbcp", "nancal"))
@EnableFluxFeign
//@Import(KotlinWebExtendConfig::class)
open class GatewayMainApplication {
    companion object {
        val logger = LoggerFactory.getLogger(this::class.java.declaringClass)
    }


    @EventListener
    fun start(ev: ApplicationStartedEvent) {
        thread(start = true, isDaemon = true) {
            while (true) {
                Thread.sleep(7_000)
                try {
                    SpringUtil.context.publishEvent(RefreshRoutesEvent(this))
                } catch (ex: Exception) {
                    logger.warn(ex.message)
                }

                Thread.sleep(8_000)
            }
        }
    }

//    @Bean
//    @LoadBalanced
//    fun webBuilder(): WebClient.Builder {
//        return WebClient.builder();
//    }
}

var started = false;

fun main(args: Array<String>) {
//    局显示定义最省事安全
//    Locale.setDefault(Locale.ENGLISH);//推荐用英语地区的算法
//    System.setProperty("user.timezone", "Asia/Shanghai");
//    TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"))
    var context = SpringApplication.run(GatewayMainApplication::class.java, *args)

    started = true;

    GatewayMainApplication.logger.Important(
        StringUtil.getCenterEachLine(
            """
﹍﹎﹍﹎﹍﹎﹎﹎﹍﹎﹍﹎﹍﹎﹎﹎﹍﹎﹍﹎﹍﹎﹎﹎﹍﹎﹍﹎﹍﹎﹎﹎﹍﹎﹎﹎﹎
${context.debugServerInfo}
﹊﹉﹊﹉﹊﹉﹊﹊﹊﹉﹊﹉﹊﹉﹊﹊﹊﹉﹊﹉﹊﹉﹊﹊﹊﹊﹉﹊﹉﹊﹉﹊﹊﹉﹊﹊﹉
""".split("\n")
        )
            .map { ' '.NewString(6) + it }
            .joinToString("\n")
    )
}


val ApplicationContext.debugServerInfo: String
    get() {
        var list = mutableListOf<String>()
        if (this is WebServerApplicationContext) {
            var port = this.environment.getProperty("server.port")
            list.add("${this.webServer.javaClass.simpleName}:${port}")
        }
        var applicationName = this.environment.getProperty("spring.application.name")
        var version = this.environment.activeProfiles.joinToString(",")
        list.add("${applicationName}:${version}")

        return list.joinToString(" -- ");
    }

